<template>
  <el-dialog
    v-model="dialogVisible"
    title="导入/同步危害"
    width="800px"
    :close-on-click-modal="false"
    :destroy-on-close="true"
    class="import-hazard-dialog"
    top="8vh"
    append-to-body
  >
    <div class="dialog-body">
      <!-- 左侧：源数据 (从哪复制) -->
      <div class="panel left-panel">
        <div class="panel-header">
          <span class="title">
            <el-icon><CopyDocument /></el-icon> 来源：复制哪些危害？
          </span>
        </div>

        <div class="panel-content">
          <el-form label-position="top" size="small" class="source-form">
            <el-form-item label="选择源工位">
              <el-cascader
                v-model="sourceCascaderValue"
                :options="cascaderOptions"
                :props="{ label: 'label', value: 'id', emitPath: false }"
                placeholder="请选择有危害的工位"
                style="width: 100%"
                filterable
                clearable
                @change="handleSourceChange"
              >
                <template #default="{ node, data }">
                  <span>{{ data.label }}</span>
                  <span v-if="!node.isLeaf" style="color: #909399; font-size: 12px; margin-left: 5px">
                    ({{ data.children?.length || 0 }})
                  </span>
                </template>
              </el-cascader>
            </el-form-item>

            <div class="hazard-list-wrapper">
              <div class="list-header">
                <!-- 显示的是去重后的数量 -->
                <span>危害列表 ({{ checkedHazardIds.length }}/{{ selectedHazards.length }})</span>
                <el-checkbox
                  v-model="checkAllHazards"
                  :indeterminate="isIndeterminate"
                  :disabled="!selectedHazards.length"
                  size="small"
                  @change="handleCheckAllChange"
                >全选</el-checkbox>
              </div>

              <div v-if="selectedHazards.length" class="list-scroll">
                <el-checkbox-group v-model="checkedHazardIds" @change="handleCheckedHazardsChange">
                  <div
                    v-for="hz in selectedHazards"
                    :key="hz.id"
                    class="hazard-row"
                    :class="{ active: checkedHazardIds.includes(hz.id) }"
                  >
                    <el-checkbox :value="hz.id" :label="hz.id" class="custom-checkbox">
                      <span class="hazard-name" :title="hz.cnName">{{ hz.cnName }}</span>
                      <el-tag size="small" :type="getHazardTagType(hz.type)" effect="plain" class="ml-2">
                        {{ getHazardTypeName(hz.type) }}
                      </el-tag>
                    </el-checkbox>
                  </div>
                </el-checkbox-group>
              </div>
              <div v-else class="empty-state">
                <el-icon size="24"><Files /></el-icon>
                <p>请先选择工位或该工位无危害</p>
              </div>
            </div>
          </el-form>
        </div>
      </div>

      <!-- 中间箭头 -->
      <div class="arrow-divider">
        <el-icon><Right /></el-icon>
      </div>

      <!-- 右侧：目标数据 (应用到哪) -->
      <div class="panel right-panel">
        <div class="panel-header">
          <span class="title">
            <el-icon><Aim /></el-icon> 目标：同步到哪里？
          </span>
          <span class="tag-count" v-if="checkedTargetCount > 0">已选 {{ checkedTargetCount }}</span>
        </div>

        <div class="panel-content">
          <el-input
            v-model="filterText"
            prefix-icon="Search"
            placeholder="搜索车间/岗位/工位..."
            size="small"
            clearable
            class="mb-2"
          />

          <div class="tree-wrapper">
            <el-tree
              ref="targetTreeRef"
              :data="targetTreeData"
              node-key="uniqueKey"
              show-checkbox
              :default-expanded-keys="expandedKeys"
              :expand-on-click-node="false"
              :filter-node-method="filterNode"
              :props="{ class: customNodeClass }"
              @check="handleTreeCheck"
            >
              <template #default="{ data }">
                <div class="custom-tree-node">
                  <el-icon v-if="data.type === 'workshop'" class="node-icon workshop"><OfficeBuilding /></el-icon>
                  <el-icon v-else-if="data.type === 'position'" class="node-icon position"><User /></el-icon>
                  <el-icon v-else class="node-icon row"><LocationInformation /></el-icon>

                  <span class="node-label" :title="data.label">{{ data.label }}</span>

                  <span v-if="data.isCurrent" class="current-badge">当前</span>
                </div>
              </template>
            </el-tree>
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <div class="footer-tips">
          <el-icon><InfoFilled /></el-icon>
          <span>提示：系统会自动去重，仅添加目标工位不存在的危害。</span>
        </div>
        <div>
          <el-button @click="close">取消</el-button>
          <el-button
            type="primary"
            :disabled="checkedHazardIds.length === 0 || checkedTargetCount === 0"
            @click="handleBatchImport"
          >
            开始同步
          </el-button>
        </div>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, ref, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox, ElTree } from 'element-plus'
import {
  CopyDocument, Right, Aim, Files, Search, InfoFilled,
  OfficeBuilding, User, LocationInformation
} from '@element-plus/icons-vue'
import { useSurveyStore, type Hazard } from '@/store/modules/survey'

const emit = defineEmits(['confirm'])
const surveyStore = useSurveyStore()

const dialogVisible = ref(false)
const currentOperatingRowId = ref<string>('')

// 左侧数据
const sourceCascaderValue = ref<string>('')
const selectedHazards = ref<Hazard[]>([])
const checkedHazardIds = ref<number[]>([])
const checkAllHazards = ref(false)
const isIndeterminate = ref(false)

// 右侧数据
const filterText = ref('')
const targetTreeRef = ref<InstanceType<typeof ElTree>>()
const checkedTargetCount = ref(0)
const expandedKeys = ref<string[]>([])

// 1. 级联选择器数据
const cascaderOptions = computed(() => {
  return (surveyStore.tabList || []).map(ws => ({
    value: `ws_${ws.id}`,
    label: ws.name,
    id: `ws_${ws.id}`,
    children: (ws.positions || []).map(pos => ({
      value: `pos_${pos.id}`,
      label: pos.name,
      id: `pos_${pos.id}`,
      children: (pos.tableData || [])
        .filter(r => r.workLocation === 1)
        .map(row => ({
          id: row.id,
          label: formatWorkRowLabel(row.testItem)
        }))
    }))
  }))
})

// 2. 树形数据
const targetTreeData = computed(() => {
  return (surveyStore.tabList || []).map((ws) => ({
    uniqueKey: `ws_${ws.id}`,
    label: ws.name,
    type: 'workshop',
    children: (ws.positions || []).map((pos) => ({
      uniqueKey: `pos_${pos.id}`,
      label: pos.name,
      type: 'position',
      children: (pos.tableData || [])
        .filter((row) => row.workLocation === 1)
        .map((row) => ({
          uniqueKey: row.id,
          label: formatWorkRowLabel(row.testItem),
          type: 'row',
          isCurrent: row.id === currentOperatingRowId.value || row.id === (currentOperatingRowId.value as any)?.originalId,
          dataRef: row,
          positionRef: pos
        }))
    }))
  }))
})

// Helpers
const formatWorkRowLabel = (testItem: any) => {
  if (!testItem) return ''
  if (typeof testItem === 'string') return testItem.replace(/<[^>]+>/g, '')
  if (typeof testItem === 'object' && testItem.content) return testItem.content
  return String(testItem)
}

const getHazardTagType = (type: number | string) => {
  const t = Number(type)
  return t === 1 ? '' : t === 2 ? 'success' : t === 3 ? 'warning' : 'info'
}

const getHazardTypeName = (type: number | string) => {
  const t = Number(type)
  return t === 1 ? '物理' : t === 2 ? '化学' : t === 3 ? '粉尘' : '其他'
}

// --- 核心逻辑修改区域开始 ---

const handleSourceChange = (val: any) => {
  const rowId = Array.isArray(val) ? val[val.length - 1] : val
  if (!rowId) {
    selectedHazards.value = []
    checkedHazardIds.value = []
    return
  }

  // 1. 查找当前选中的工位数据
  let foundRow: any = null
  for (const ws of surveyStore.tabList) {
    for (const pos of ws.positions || []) {
      const r = pos.tableData?.find(item => item.id === rowId)
      if (r) {
        foundRow = r
        break
      }
    }
    if (foundRow) break
  }

  // 2. 获取危害列表并去重
  if (foundRow && foundRow.hazards) {
    // 步骤A: 过滤掉已删除的
    const validHazards = foundRow.hazards.filter(
      (h: any) => !h.deletedInPage1 && !h.deletedInPage2
    )

    // 步骤B: 按 cnName 去重
    const uniqueMap = new Map()
    const distinctHazards: Hazard[] = []

    validHazards.forEach((h: any) => {
      // 如果名称存在且未被记录过，则加入列表
      if (h.cnName && !uniqueMap.has(h.cnName)) {
        uniqueMap.set(h.cnName, true)
        distinctHazards.push(h)
      }
    })

    // 赋值给 selectedHazards (深拷贝防止修改源数据)
    selectedHazards.value = JSON.parse(JSON.stringify(distinctHazards))

    // 默认全选
    checkedHazardIds.value = selectedHazards.value.map(h => h.id)
    checkAllHazards.value = true
    isIndeterminate.value = false
  } else {
    selectedHazards.value = []
    checkedHazardIds.value = []
  }
}
// --- 核心逻辑修改区域结束 ---

const handleCheckAllChange = (val: boolean) => {
  checkedHazardIds.value = val ? selectedHazards.value.map(h => h.id) : []
  isIndeterminate.value = false
}

const handleCheckedHazardsChange = (value: number[]) => {
  const count = value.length
  checkAllHazards.value = count === selectedHazards.value.length
  isIndeterminate.value = count > 0 && count < selectedHazards.value.length
}

watch(filterText, (val) => {
  targetTreeRef.value!.filter(val)
})

const filterNode = (value: string, data: any) => {
  if (!value) return true
  return data.label.includes(value)
}

const handleTreeCheck = () => {
  const checkedNodes = targetTreeRef.value?.getCheckedNodes(false, false) || []
  checkedTargetCount.value = checkedNodes.filter((n: any) => n.type === 'row').length
}

const customNodeClass = (data: any) => {
  if (data.type === 'row') return 'is-row-node'
  return ''
}

const findPathKeysForRow = (rowId: string): string[] => {
  for (const ws of surveyStore.tabList) {
    for (const pos of ws.positions || []) {
      const r = pos.tableData?.find(item => item.id === rowId)
      if (r) {
        return [`ws_${ws.id}`, `pos_${pos.id}`]
      }
    }
  }
  return []
}

const open = (currentRow?: any) => {
  dialogVisible.value = true
  filterText.value = ''
  currentOperatingRowId.value = currentRow ? currentRow.id : ''
  expandedKeys.value = []

  if (currentRow) {
    sourceCascaderValue.value = currentRow.id
    handleSourceChange(currentRow.id)
    const pathKeys = findPathKeysForRow(currentRow.id)
    expandedKeys.value = pathKeys
  } else {
    sourceCascaderValue.value = ''
    selectedHazards.value = []
    checkedHazardIds.value = []
  }

  nextTick(() => {
    if (targetTreeRef.value) {
      targetTreeRef.value.setCheckedKeys([])
      if (currentRow) {
        targetTreeRef.value.setCheckedKeys([currentRow.id])
        setTimeout(() => {
          const el = document.querySelector('.current-badge')
          if (el) el.scrollIntoView({ block: 'center', behavior: 'smooth' })
        }, 100)
      }
      handleTreeCheck()
    }
  })
}

const close = () => {
  dialogVisible.value = false
}

const handleBatchImport = async () => {
  const checkedNodes = targetTreeRef.value?.getCheckedNodes(false, false) || []
  const targetRows = checkedNodes.filter((n: any) => n.type === 'row')

  // 此时 hazardsToSync 已经是去重后的列表
  const hazardsToSync = selectedHazards.value.filter(h => checkedHazardIds.value.includes(h.id))

  if (!targetRows.length || !hazardsToSync.length) return

  try {
    await ElMessageBox.confirm(
      `确定将 ${hazardsToSync.length} 个危害同步到 ${targetRows.length} 个目标工位吗？`,
      '同步确认',
      { confirmButtonText: '确定同步', cancelButtonText: '取消', type: 'primary' }
    )

    let totalCount = 0
    targetRows.forEach((node: any) => {
      const targetRow = node.dataRef
      if (!targetRow.hazards) targetRow.hazards = []

      const workContent = formatWorkRowLabel(targetRow.testItem).replace(/工位$/, '')
      // 构造新属性
      const newSourcePrefix = `${workContent}时产生`
      const newContactTiming = `${workContent}时`
      const newWorkContent = `${workContent}工作`

      hazardsToSync.forEach((srcHazard) => {
        // 目标去重校验：检查目标行是否已经有了同名危害
        const exists = targetRow.hazards.some((h: any) =>
          h.cnName === srcHazard.cnName && !h.deletedInPage1 && !h.deletedInPage2
        )

        if (!exists) {
          const newHazard = JSON.parse(JSON.stringify(srcHazard))
          // 赋予新ID，确保独立
          newHazard.id = Date.now() + Math.floor(Math.random() * 100000)
          // 更新动态字段
          newHazard.source = `${newSourcePrefix}${newHazard.cnName}`
          newHazard.contactTiming = newContactTiming
          newHazard.workContent = newWorkContent
          newHazard.workLocation = 1

          // 如果目标有接触时间，同步过去
          const targetTime = parseFloat(targetRow.contactTime || '0')
          if (targetTime > 0 && newHazard.sampling) {
            newHazard.sampling.contactHours = targetTime
          }

          targetRow.hazards.push(newHazard)
          totalCount++
        }
      })
    })

    ElMessage.success(`同步成功！已添加 ${totalCount} 条记录`)
    // 通知父组件哪些工位被更新，便于重算拆分逻辑和同步到劳动者行
    const targetRowIds = targetRows
      .map((node: any) => node.dataRef && node.dataRef.id)
      .filter((id: any) => !!id)
    emit('confirm', { targetRowIds })
    close()
  } catch (e) { }
}

defineExpose({ open, close })
</script>

<style scoped lang="scss">
.dialog-body {
  display: flex;
  height: 650px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  overflow: hidden;
  background-color: #fcfcfc;
}

.panel {
  display: flex;
  flex-direction: column;
  padding: 0;

  &.left-panel {
    width: 320px;
    background-color: #fff;
    border-right: 1px solid #f0f2f5;
  }

  &.right-panel {
    flex: 1;
    background-color: #fff;
  }

  .panel-header {
    height: 48px;
    padding: 0 16px;
    background-color: #f5f7fa;
    border-bottom: 1px solid #ebeef5;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .title {
      font-weight: 600;
      color: #303133;
      font-size: 14px;
      display: flex;
      align-items: center;
      gap: 6px;
    }

    .tag-count {
      font-size: 12px;
      color: #409eff;
      background: #ecf5ff;
      padding: 2px 8px;
      border-radius: 10px;
    }
  }

  .panel-content {
    flex: 1;
    overflow: hidden;
    padding: 16px;
    display: flex;
    flex-direction: column;
  }
}

.arrow-divider {
  width: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fcfcfc;
  color: #909399;
  font-size: 20px;
}

.source-form {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.hazard-list-wrapper {
  flex: 1;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .list-header {
    padding: 8px 12px;
    background: #f0f2f5;
    border-bottom: 1px solid #dcdfe6;
    font-size: 12px;
    color: #606266;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .list-scroll {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
    background: #fff;
  }

  .hazard-row {
    padding: 6px 8px;
    border-radius: 4px;
    margin-bottom: 2px;
    transition: background 0.2s;

    &:hover {
      background-color: #f5f7fa;
    }
    &.active {
      background-color: #ecf5ff;
    }

    .custom-checkbox {
      width: 100%;
      margin-right: 0;
      :deep(.el-checkbox__label) {
        flex: 1;
        display: flex;
        justify-content: space-between;
        align-items: center;
      }
    }
    .hazard-name {
      font-size: 13px;
      color: #303133;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 220px;
    }
  }

  .empty-state {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #909399;
    gap: 10px;
    p { font-size: 12px; }
  }
}

.tree-wrapper {
  flex: 1;
  overflow-y: auto;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 5px;
}

.custom-tree-node {
  display: flex;
  align-items: center;
  font-size: 13px;
  width: 100%;

  .node-icon {
    margin-right: 6px;
    font-size: 14px;
    &.workshop { color: #909399; }
    &.position { color: #e6a23c; }
    &.row { color: #67c23a; }
  }

  .node-label {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .current-badge {
    font-size: 10px;
    color: #fff;
    background-color: #409eff;
    padding: 0 4px;
    border-radius: 2px;
    margin-left: 8px;
    flex-shrink: 0;
  }
}

:deep(.el-tree-node__content) {
  height: 30px;
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;

  .footer-tips {
    display: flex;
    align-items: center;
    color: #909399;
    font-size: 12px;
    gap: 4px;
  }
}

:deep(.el-dialog__body) {
  padding: 20px;
}
</style>
